import re
from datetime import datetime

import pdfplumber

def extract_trip_info(pdf_path):
    with pdfplumber.open(pdf_path) as pdf:
        page = pdf.pages[0]
        text_lines = page.extract_text().split("\n")
        # 找到包含 '申请日期' 的行
        basic_info_line = None
        caocao = False
        didi = False
        gaodei = False
        yangguang = False
        ditie = False
        date_obj = ""

        for line in text_lines:
            # 根据各大平台的名称进行区分
            if "百度地图" in line:
                caocao = True
            elif "滴滴" in line:
                didi = True
            elif "高德" in line:
                gaodei = True
            elif "阳光" in line:
                yangguang = True
            elif "地铁" in line:
                ditie = True
            # 得到申请日期所在的行
            if ("申请日期" in line) | ("申请时间" in line):
                basic_info_line = line
                break

        if basic_info_line is None:
            print("未找到包含申请日期的行")
            return None

        if caocao :
            date_obj = get_caocao_date(basic_info_line)
        elif didi or yangguang:
            date_obj = get_didi_date(basic_info_line)
        elif gaodei:
            date_obj = get_gaodei_date(basic_info_line)
        elif ditie:
            date_obj = get_ditie_date(basic_info_line)
        else :
            date_obj = get_other_date(basic_info_line) 
        
        # 提取表格信息
        table = page.extract_table()
        if not table:
            print("未找到表格数据")
            return None
        headers = table[0]  # 第一行作为表头
        rows = table[1:]  # 后续行作为数据

        # 将表格数据转换为字典列表
        table_data = []
        for row in rows:
            # row=clear_n(row)
            if gaodei:
                row = split_with_datetime(row)
                row = multiple_lines(row,headers)

            item = dict(zip(headers, row))
            # 提取所需信息
            extracted_info = {
                "用车时间": get_content(item, ["时间","日期"]).replace("\n", " "),
                "起点": get_content(item, ["起点","上车地点"]),
                "终点": get_content(item, ["终点","下车地点"]),
                "金额": extract_amount(get_content(item, ["金额", "费用"])),
                "里程": get_content(item, ["里程"]),
            }
            if ditie:
                info = get_content(item,["行程站点"])
                if info:
                    route_str = str(info).strip()
                    parts = route_str.split("-", 1)
                    start_point = parts[0].strip() if len(parts) > 0 else ""
                    end_point = parts[1].strip() if len(parts) > 1 else ""
                    extracted_info["起点"] = start_point
                    extracted_info["终点"] = end_point
                    date_time = get_content2(item,["日期","时间"])
                    date_time = get_date_time_info(date_time)
                    extracted_info["用车时间"] = date_time
            table_data.append(extracted_info)
        result = {
            "基本信息": {"类别": "行程单", "申请日期": date_obj, "行程日期": ""},
            "表格内容": table_data,
        }
        return result

def clear_n(headers):
    for header in headers:
        header=header.replace("\n","")
    
def multiple_lines(row,headers):
    index = 0
    for header in headers:
        if header == "终点" or header == "起点":
            if ' ' in row[index] and is_amount_with_unit(row[index + 1]):
                element = row[index]
                elements = row[index].split(" ")
                row[index] = elements[0]
                money = row[index + 1]
                row[index + 1] = elements[1]
                row.append(money)
                # row.indert(index + 2,money)
            break
        index += 1 
  
    print(len(row))
    print(row)
    print(headers)
    return row

def is_amount_with_unit(element):
    """判断字符串是否为“金额+单位”格式"""
    # 正则规则：数字（可含小数点，最多两位小数）+“元”结尾
    pattern = r'^\d+\.\d{2}元$'
    pattern2=r'^\d+\.\d{2}$'
    return bool(re.match(pattern, element)) or bool(re.match(pattern2,element))

def split_with_datetime(s):
    datetimes = get_date_time_info(s[0])
    placeholder = "||DATETIME||"
    start = ""
    # 替换日期时间为占位符
    s_replaced = s[0]
    # for dt in datetimes:

    s_replaced = s_replaced.replace(datetimes, placeholder, 1)

    if "\n" in s_replaced:
        ss = s_replaced.split("\n")
        for s2 in ss:
            if placeholder in s2:
                s_replaced = s2
            else:
                start += s2
        print(start)

    # 分割字符串
    parts = s_replaced.split()

    # 恢复日期时间（添加安全检查）
    result = []
    i = 0
    for part in parts:
        if part == placeholder:
            result.append(datetimes)
        else:
            result.append(part)
        if i == 4 and start != "":
            result.append(start)
        i += 1

    return result


def extract_amount(amount_text: str) -> float:
    """
    从形如 '￥58' 的字符串中提取金额数字部分
    """
    match = re.search(r"\d+(\.\d+)?", amount_text)
    if match:
        return float(match.group())
    else:
        return 0.0  # 或者返回 None


def get_xingcheng_date(text_lines):
    lines = []
    for line in text_lines:
        if "年" in line and "月" in line and "日" in line:
            lines.append(line)
        if "申请日期" in line or "申请时间" in line:
            lines.append(line)
    lines.sort(key=sort_key)
    if len(lines)==1:
        return lines[0]
    else :
        for line in lines:
            if ("申请日期" in line or "申请时间" in line) and "年" in line and "月" in line:
                return line
            elif "年" in line and "月" in line and "日" in line:
                return line
            elif "年" in line and "月" in line:
                return line
            elif "申请日期" in line or "申请时间" in line :
                return line
            else:
                return lines[0]
    return None


def sort_key(item):
    # 将元素转为字符串，判断是否包含数字
    item_str = str(item)
    # 若包含数字，返回0（权重低，排前面）；否则返回1（权重高，排后面）
    if re.search(r'\d', item_str):  # 正则匹配数字
        return 0
    else:
        return 1


def get_caocao_date(basic_info_line: str):
    # 提取申请日期
    application_date_str = get_xingcheng_date(basic_info_line.split("|"))
    application_date_str = application_date_str.replace("申请日期：", "").strip()
    return get_date(get_date_info(application_date_str))


def get_didi_date(basic_info_line: str):
    # 提取申请日期
    application_date_str = get_xingcheng_date(basic_info_line.split("·"))
    application_date_str = application_date_str.replace("申请日期：", "").strip()
    return get_date(get_date_info(application_date_str))


def get_gaodei_date(basic_info_line: str):
    # 提取申请日期
    application_date_str = get_xingcheng_date(basic_info_line.split(" "))
    application_date_str = application_date_str.replace("申请日期：", "").strip()
    return get_date(get_date_info(application_date_str))

def get_ditie_date(basic_info_line: str):
    #提取申请日期
    application_date_str = basic_info_line.replace("申请日期：", "").strip()
    return get_date(get_date_info(application_date_str))
    

def get_other_date(basic_info_line: str):
    # 提取申请日期
    application_date_str=get_xingcheng_date(basic_info_line.split(" "))
    application_date_str = application_date_str.replace("申请日期：", "").strip()
    return get_date(get_date_info(application_date_str))



def get_date_info(date_time: str) -> str:
    pattern = r"\d{4}[-/]\d{1,2}[-/]\d{1,2}"
    match = re.search(pattern, date_time)
    if match:
        return match.group(0)
    else:
        return date_time


def get_date_time_info(date_time: str) -> str:
    date_time = convert_to_standard_datetime(date_time)
    if(date_time):
        pattern = r"\d{4}[-/]\d{1,2}[-/]\d{1,2} \d{2}[:]\d{2}"
        match = re.search(pattern, date_time)
        if match:
            return match.group(0)
    else:
        return None

def convert_to_standard_datetime(date_time: str) -> str:
    ## 统一时间格式：yyyy-MM-dd HH:mm
    if not date_time:
        return None  # 处理空输入
    
    # 1. 定义所有可能的日期时间格式正则（覆盖常见场景）
    # 格式1：年-月-日 时:分 / 年/月/日 时:分（纯数字分隔）
    pattern1 = r"(\d{4})[-/](\d{1,2})[-/](\d{1,2})\s+(\d{2}):(\d{2})"
    # 格式2：年.月.日 时:分（点分隔）
    pattern2 = r"(\d{4})\.(\d{1,2})\.(\d{1,2})\s+(\d{2}):(\d{2})"
    # 格式3：年年月日 时:分（带“年/月/日”字，如 2025年09月19日 15:58）
    pattern3 = r"(\d{4})年(\d{1,2})月(\d{1,2})日?\s+(\d{2}):(\d{2})"
    # 格式4：带时间段的场景（如 2025年09月19日 15:58-17:32，提取前半段）
    pattern4 = r"(\d{4})年(\d{1,2})月(\d{1,2})日?\s+(\d{2}):(\d{2})(?=-)"

    # 2. 按优先级匹配正则，提取年、月、日、时、分
    match = None
    parse_format = None  # 标记当前匹配的格式，用于后续解析
    
    # 先匹配带“年/月/日”的格式（更常见）
    if not match:
        match = re.search(pattern3, date_time)
        if match:
            parse_format = "ymd"  # 年、月、日分别对应分组1-3，时-分对应4-5
    
    # 再匹配时间段中的日期时间
    if not match:
        match = re.search(pattern4, date_time)
        if match:
            parse_format = "ymd"
    
    # 匹配纯数字分隔格式（- / .）
    if not match:
        match = re.search(pattern1, date_time) or re.search(pattern2, date_time)
        if match:
            parse_format = "num"  # 年、月、日分别对应分组1-3，时-分对应4-5
    
    # 3. 解析匹配结果，转为标准格式
    if match and parse_format:
        # 提取分组数据（年、月、日、时、分）
        year, month, day, hour, minute = match.groups()
        # 补全单数字为两位数（如 9月→09月，8时→08时）
        month = f"{int(month):02d}"
        day = f"{int(day):02d}"
        hour = f"{int(hour):02d}"
        minute = f"{int(minute):02d}"
        # 拼接为 yyyy-MM-dd HH:mm 格式
        return f"{year}-{month}-{day} {hour}:{minute}"
    
    # 4. 若所有格式都不匹配，返回原始匹配结果（或None，根据需求调整）
    # （可选） fallback：返回原始提取的未格式化字符串
    raw_match = re.search(r"\d{4}[-/年.]\d{1,2}[-/月.]\d{1,2}[日]?\s+\d{2}:\d{2}", date_time)
    return raw_match.group(0) if raw_match else None

def get_date(application_date_str):
    if application_date_str == None:
        return None
    try:
        # 尝试解析 'yyyy-MM-dd' 格式
        return (
            datetime.strptime(application_date_str, "%Y-%m-%d")
            .date()
            .strftime("%Y-%m-%d")
        )
    except ValueError:
        try:
            # 尝试解析 'yyyy年MM月dd日' 格式
            return (
                datetime.strptime(application_date_str, "%Y年%m月%d日")
                .date()
                .strftime("%Y-%m-%d")
            )
        except ValueError:
            print(f"无法解析申请日期: {application_date_str}")
            return None


def get_content(item, keys):
    # 初始化用车时间为空字符串
    use_time = ""
    # 遍历 item 字典的键
    for key_one in keys:
        for key in item:
            if key_one in key:
                use_time = item[key]
                break
    return use_time

def get_content2(item, keys):
    # 初始化用车时间为空字符串
    use_time = ""
    # 遍历 item 字典的键
    for key_one in keys:
        for key in item:
            if key_one in key:
                use_time +=  item[key] if use_time == "" else (" " + item[key])
    return use_time